cmake_minimum_required(VERSION 3.22.1)
project(grpc_mobile CXX)

# 选项设置
option(BUILD_CLIENT "Build client" ON)
option(BUILD_SERVER "Build server" ON)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "")

# 语言设置
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POLICY_VERSION_MINIMUM 3.5)

# 编译设置
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions")
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-dead_strip")
    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-dead_strip")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-S")
    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-S")
else()
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s")
    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -s")
endif()

# ccache
find_program(CCACHE_FOUND ccache)
if(CCACHE_FOUND)
    message(STATUS "Found ccache: ${CCACHE_FOUND}")
    set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
    set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif(CCACHE_FOUND)

# 依赖库
set(protobuf_MODULE_COMPATIBLE ON CACHE BOOL "")
find_package(Threads REQUIRED)
set(ABSL_ENABLE_INSTALL ON)
set(ABSL_PROPAGATE_CXX_STD ON)
set(gRPC_USE_PROTO_LITE ON CACHE BOOL "Use the protobuf-lite library")
set(protobuf_DISABLE_RTTI ON CACHE BOOL "Remove runtime type information in the binaries" FORCE)

add_subdirectory(third_party/grpc ${CMAKE_BINARY_DIR}/grpc EXCLUDE_FROM_ALL)
set(_PROTOBUF_LIBPROTOBUF ${_gRPC_PROTOBUF_LIBRARIES})
if(CMAKE_CROSSCOMPILING)
    find_program(_PROTOBUF_PROTOC protoc PATHS ${PROTOBUF_BINARY_DIR})
else()
    set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)
endif()
set(_GRPC_GRPCPP grpc++)
if(CMAKE_CROSSCOMPILING)
    find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin PATHS ${GRPC_BINARY_DIR})
else()
    set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:grpc_cpp_plugin>)
endif()

# protobuf生成
include(cmake/grpc_cpp_generate.cmake)
set(PROTO_FILES ${CMAKE_CURRENT_SOURCE_DIR}/proto/device_communication.proto)
set(PROTO_OUTPUT_DIR ${CMAKE_BINARY_DIR}/proto)
file(MAKE_DIRECTORY ${PROTO_OUTPUT_DIR})  # 确保输出目录存在

add_library(grpc_proto_object OBJECT)
grpc_cpp_generate(
    TARGET grpc_proto_object
    PROTOS ${PROTO_FILES}
    OUTPUT_DIR ${PROTO_OUTPUT_DIR}
)
target_link_libraries(grpc_proto_object PRIVATE
    ${_PROTOBUF_LIBPROTOBUF}
    ${_GRPC_GRPCPP}
    Threads::Threads)
target_include_directories(grpc_proto_object PUBLIC ${GRPC_GEN_OUTPUT_DIR})

if (BUILD_CLIENT)
    add_subdirectory(src/client)
endif()
add_subdirectory(src/server)